package co.recloud.ariadne.store;

import co.recloud.ariadne.config.Configuration;
import co.recloud.ariadne.list.SelfOrganizingList;
import co.recloud.ariadne.model.Address;
import co.recloud.ariadne.model.Host;
import co.recloud.ariadne.model.Location;
import co.recloud.ariadne.model.logical.Transaction;

import java.util.HashMap;
import java.util.Map;

public class AddressTable {
	private static AddressTable singleton;

    private Map<Integer, Integer> table;
    private SelfOrganizingList<Integer> frequency;
    
    public AddressTable() {
        int size = Configuration.ADDRESS_TABLE_SIZE;
        table = new HashMap<Integer, Integer>(size);
        frequency = new SelfOrganizingList<Integer>(size);
    }

	public synchronized static AddressTable getInstance() {
		if(singleton == null) {
			singleton = new AddressTable();
		}
		return singleton;
	}
	public Host resolve(String columnFamily, String key) {
		String path = columnFamily + ":" + key;
        return resolvePath(path);
	}

    public AddressTable remap(int oldBlock, int newBlock) {
        table.put(oldBlock, newBlock);
        return this;
    }
    public static int[] hash(String path) {
        int hashCode = path.hashCode();
        return hash(hashCode);
    }
    
    public static int[] hash(int hashCode) {
        int[] coords = new int[2];
        coords[0] = hashCode >>> 16;
        coords[1] = (hashCode << 16) >>> 16;
        return coords;
    }
    
    public int translatePath(String path) {
        int hashVal = path.hashCode();
        return translateBlock(hashVal);
    }

    public int translateBlock(int block) {
        if(table.containsKey(block)) {
            return table.get(block);
        }
        return block;
    }

    private Host resolvePath(String path) {
        int hashVal = translatePath(path);
        Long hash = new Long(hashVal);
        HostTable ht = HostTable.getInstance();
        Host host = ht.findByHash(hash);
        frequency.lookup(path.hashCode());
        return host;
    }
    
    public boolean isLocalPath(String path) {
        HostTable ht = HostTable.getInstance();
        if(ht.getLocalhost().equals(resolvePath(path))) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isPathRanked(String path) {
        return frequency.contains(path.hashCode());
    }

    public void propogate(int address) {

    }
}
